library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

library work;
use work.wr_pkg.all;

entity xwr_udp_rx is
port (
    --// clk, reset
    rst_n_i       : in std_logic;
    clk_sys_i     : in std_logic;

    raw_snk_i     : in  t_wrf_sink_in;
    raw_snk_o     : out t_wrf_sink_out;

    fifo_wrdata_o   : out std_logic_vector(15 downto 0);  -- fifo dout
    fifo_wrclk_o    : out std_logic;
    fifo_wren_o     : out std_logic;
    fifo_full_i     : in  std_logic;
    fifo_prog_full_i: in  std_logic
);
end entity;

architecture rtl of xwr_udp_rx is

component snk_to_mac is
port (
    clk_sys_i        : in std_logic;
    rst_n_i          : in std_logic;

    snk_i            : in  t_wrf_sink_in;
    snk_o            : out t_wrf_sink_out;
    mac_rx_data      : out std_logic_vector(15 downto 0);
    mac_rx_data_valid: out std_logic;
    mac_rx_sof       : out std_logic;
    mac_rx_eof       : out std_logic
);
end component;

component mac_to_ip is
port (
    clk_sys_i: in std_logic;
    rst_n_i: in std_logic;
    mac_rx_data: in std_logic_vector(15 downto 0);
    mac_rx_data_valid: in std_logic;
    mac_rx_sof: in std_logic;
    mac_rx_eof: in std_logic;
    ip_rx_data: out std_logic_vector(15 downto 0);
    ip_rx_data_valid: out std_logic;
    ip_rx_sof: out std_logic;
    ip_rx_eof: out std_logic;
    ip_byte_count: out std_logic_vector(15 downto 0);
    ip_header_flag: out std_logic;
    rx_udp_cksum: out std_logic_vector(16 downto 0);
    rx_udp_cksum_rdy: out std_logic
);
end component;

component ip_to_udp is
port (
    clk_sys_i: in std_logic;
    rst_n_i: in std_logic;
    ip_rx_data: in std_logic_vector(15 downto 0);
    ip_rx_data_valid: in std_logic;
    ip_rx_sof: in std_logic;
    ip_rx_eof: in std_logic;
    ip_byte_count: in std_logic_vector(15 downto 0);
    ip_header_flag: in std_logic;
    rx_udp_cksum: in std_logic_vector(16 downto 0);
    rx_udp_cksum_rdy: in std_logic;
    udp_rx_data: out std_logic_vector(15 downto 0);
    udp_rx_data_valid: out std_logic;
    udp_rx_sof: out std_logic;
    udp_rx_eof: out std_logic
);
end component;

component udp_to_fifo is
port (
    clk_sys_i        : in std_logic;
    rst_n_i          : in std_logic;
    udp_rx_data      : in std_logic_vector(15 downto 0);
    udp_rx_data_valid: in std_logic;
    udp_rx_sof       : in std_logic;
    udp_rx_eof       : in std_logic;
    fifo_wrdata      : out std_logic_vector(15 downto 0);  -- fifo dout
    fifo_wrclk       : out std_logic;
    fifo_wren        : out std_logic;
    fifo_full        : in  std_logic;
    fifo_prog_full   : in  std_logic
);
end component;

signal mac_rx_data      : std_logic_vector(15 downto 0);
signal mac_rx_data_valid: std_logic;
signal mac_rx_sof       : std_logic;
signal mac_rx_eof       : std_logic;

signal ip_rx_data       : std_logic_vector(15 downto 0);
signal ip_rx_data_valid : std_logic;
signal ip_rx_sof        : std_logic;
signal ip_rx_eof        : std_logic;
signal ip_byte_count    : std_logic_vector(15 downto 0);
signal ip_header_flag   : std_logic;
signal rx_udp_cksum     : std_logic_vector(16 downto 0);
signal rx_udp_cksum_rdy : std_logic;

signal udp_rx_data         : std_logic_vector(15 downto 0);
signal udp_rx_data_valid   : std_logic;
signal udp_rx_sof          : std_logic;
signal udp_rx_eof          : std_logic;

begin

u_mac_rx:snk_to_mac
port map(
    clk_sys_i        => clk_sys_i,
    rst_n_i          => rst_n_i,
    snk_i            => raw_snk_i,
    snk_o            => raw_snk_o,
    mac_rx_data      => mac_rx_data,
    mac_rx_data_valid=> mac_rx_data_valid,
    mac_rx_sof       => mac_rx_sof,
    mac_rx_eof       => mac_rx_eof
);

u_ip_rx:mac_to_ip
port map(
    clk_sys_i        => clk_sys_i,
    rst_n_i          => rst_n_i,
    mac_rx_data      => mac_rx_data,
    mac_rx_data_valid=> mac_rx_data_valid,
    mac_rx_sof       => mac_rx_sof,
    mac_rx_eof       => mac_rx_eof,
    ip_rx_data       => ip_rx_data,
    ip_rx_data_valid => ip_rx_data_valid,
    ip_rx_sof        => ip_rx_sof,
    ip_rx_eof        => ip_rx_eof,
    ip_byte_count    => ip_byte_count,
    ip_header_flag   => ip_header_flag,
    rx_udp_cksum     => rx_udp_cksum,
    rx_udp_cksum_rdy => rx_udp_cksum_rdy
);

u_udp_rx:ip_to_udp
port map(
    clk_sys_i        => clk_sys_i,
    rst_n_i          => rst_n_i,
    ip_rx_data       => ip_rx_data,
    ip_rx_data_valid => ip_rx_data_valid,
    ip_rx_sof        => ip_rx_sof,
    ip_rx_eof        => ip_rx_eof,
    ip_byte_count    => ip_byte_count,
    ip_header_flag   => ip_header_flag,
    rx_udp_cksum     => rx_udp_cksum,
    rx_udp_cksum_rdy => rx_udp_cksum_rdy,
    udp_rx_data      => udp_rx_data,
    udp_rx_data_valid=> udp_rx_data_valid,
    udp_rx_sof       => udp_rx_sof,
    udp_rx_eof       => udp_rx_eof
);

u_udp_fifo:udp_to_fifo
port map(
    clk_sys_i        => clk_sys_i,
    rst_n_i          => rst_n_i,
    udp_rx_data      => udp_rx_data,
    udp_rx_data_valid=> udp_rx_data_valid,
    udp_rx_sof       => udp_rx_sof,
    udp_rx_eof       => udp_rx_eof,
    fifo_wrdata      => fifo_wrdata_o,
    fifo_wrclk       => fifo_wrclk_o,
    fifo_wren        => fifo_wren_o,
    fifo_full        => fifo_full_i,
    fifo_prog_full   => fifo_prog_full_i
);

end architecture ; -- rtl
